/*********************************************************************************
 *      Copyright:  (C) 2014 EAST
 *                  All rights reserved.
 *
 *       Filename:  msgque.c
 *    Description:  This file is used to deal message queue. 
 *                 
 *        Version:  1.0.0(07/29/2014)
 *         Author:  fulinux <fulinux@sina.com>
 *      ChangeLog:  1, Release initial version on "07/29/2014 08:30:29 AM"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <fcntl.h>

#include "msgque.h"

int msgque_read (msgque_t *msgque)
{
    msgque_t *pmsgque = msgque;

    if(pmsgque == NULL){
        errno = EINVAL;
        return -1;
    }

    /* 设置msgflg的默认值 */
    if(!pmsgque->msgflg){
        pmsgque->msgflg = MSG_NOERROR;
    }

    /* 接收消息队列 */
    if(-1 == msgrcv(pmsgque->msgid, (void *)&pmsgque->msgbuf, MSGSIZE, 0, pmsgque->msgflg)){
        if(pmsgque->debug)
            fprintf(stderr, "msgrcv failed with error: %s\n", strerror(errno));
        return -1;
    }

    return 0;
} /* ----- End of msgque_read()  ----- */


int msgque_write (msgque_t *msgque)
{
    msgque_t *pmsgque = msgque;

    if(pmsgque == NULL){
        errno = EINVAL;
        return -1;
    }

    /* 设置msgflg的默认值 */
    if(!pmsgque->msgflg){
        pmsgque->msgflg = IPC_NOWAIT;
    }

    /* 发送消息队列 */
    if(-1 == msgsnd(pmsgque->msgid, (void *)&pmsgque->msgbuf, MSGSIZE, pmsgque->msgflg)){
        if(pmsgque->debug)
            fprintf(stderr, "msgsnd failed with error: %s\n", strerror(errno));
        return -1;
    }

    return 0;
} /* ----- End of msgque_write()  ----- */

int msgque_setdebug(msgque_t *msgque, int flag)
{
    msgque_t *pmsgque = msgque;

    pmsgque->debug = flag;

    return 0;
}

int msgque_init (msgque_t *msgque, int fid)
{
    key_t key;                  
    msgque_t *pmsgque = msgque;

    if(0 != access(MSGQUEFILE, F_OK)){
        if(-1 == creat(MSGQUEFILE, O_CREAT)){
            perror("CREATE");
            return -1;
        }
    }

    key = ftok(MSGQUEFILE, fid);
    if(-1 == key){
        perror("FTOK");
        return -1;
    }

    pmsgque->msgid = msgget(key, IPC_EXCL); /* 检查消息队列是否存在 */
    if ( pmsgque->msgid < 0 ){
        pmsgque->msgid = msgget(key, IPC_CREAT | 0666); /* 创建消息队列 */
        if ( pmsgque->msgid < 0 ){
            fprintf(stderr, "msgget failed with error: %s\n", strerror(errno));
            return -1;
        }
    }

    return 0;
} /* ----- End of msgque_init() ----- */

int msgque_exit (msgque_t *msgque)
{
    msgque_t *pmsgque = msgque;

    if(NULL == pmsgque->msgbuf.mtext)
        free(pmsgque->msgbuf.mtext);

    /* 删除消息队列 */
    if (msgctl(pmsgque->msgid, IPC_RMID, 0) == -1){
        if(pmsgque->debug)
            fprintf(stderr, "msgctl(IPC_RMID) failed with error: %s\n", strerror(errno));
        return -1;
    }

    remove(MSGQUEFILE);

    return 0;
} /* ----- End of msgque_exit()  ----- */

